package org.brownflat.lighthouse.monitoring.ci;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.io.InputStream;

public abstract class HTTPServer {

    private String host;
    private int port;
    private static final Logger LOG = Logger.getLogger(HTTPServer.class);
    private String path = "";

    public HTTPServer(String host, int port) {
        this.host = host;
        this.port = port;
    }

    public HTTPServer(String host, int port, String path) {
        this.host = host;
        this.port = port;
        this.path = path;
    }

    public String execute(HTTPRequest request) throws ConnectionException {
        String fullUrl = getFullURL(request);
        HttpMethod method = new GetMethod(fullUrl);
        method.getParams().setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
        HttpClient client = new HttpClient();

        LOG.debug("Requesting URL from server: " + fullUrl);
        return execute(method, client);
    }

    public String getFullURL(HTTPRequest request) {
        return getUrl() + "/" + request.getURI();
    }

    private String execute(HttpMethod method, HttpClient client) throws ConnectionException {
        try {
            int code = client.executeMethod(method);
            if (code != 200) {
                throw new ConnectionException("HTTP Response Code: " + code);
            }
            return slurp(method.getResponseBodyAsStream()).replace("\n", "");
        } catch (HttpException e) {
            throw new ConnectionException(e);
        } catch (IOException e) {
            throw new ConnectionException(e);
        }
    }

    private String slurp(InputStream in) throws IOException {
        StringBuffer out = new StringBuffer();
        byte[] b = new byte[4096];
        for (int n; (n = in.read(b)) != -1; ) {
            out.append(new String(b, 0, n));
        }
        return out.toString();
    }

    public String getUrl() {
        return "http://" + host + ":" + port + (path.length() > 0 ? "/" + path + "/" : "");
    }
}
